#include <python2.4/Python.h>
#include "IoPython.h"
#include "PyIo.h"

// This object wrap a method of a PyIo object. All it does is override the call method,
// looking up and forwarding that call to Io


typedef struct {
    PyObject_HEAD
    /* Type-specific fields go here. */
	IoObject *self;
	IoObject *method;
	IoSymbol *methodName;
} pyIoMethodObject;

static PyObject *
pyIoMethod_call(pyIoMethodObject *obj, PyObject *args, PyObject *other)
{
    PyObject *result;
	IoObject *o = obj->self;
	IoMessage *m = IoMessage_newWithName_(o->state, obj->methodName);
	int i;
	for(i=0;i<PyTuple_Size(args);i++) {
		// Set arguments
		PyObject *pyarg;
		pyarg = PyTuple_GetItem(args, i);
		IoObject *arg = convertPy(o, pyarg); // Incref? 
		// Decref?
		IoMessage_addCachedArg_(m, arg);
	}
	
	IoObject_perform(o, o, m);
	Py_INCREF(obj);
    return (PyObject *) obj;
}
static PyTypeObject pyIoMethodType = {
    PyObject_HEAD_INIT(NULL)
    0,                         /*ob_size*/
    "IoPython.pyIoMethod",             /*tp_name*/
    sizeof(pyIoMethodObject), /*tp_basicsize*/
    0,                         /*tp_itemsize*/
    0,                         /*tp_dealloc*/
    0,                         /*tp_print*/
    0,                         /*tp_getattr*/
    0,                         /*tp_setattr*/
    0,                         /*tp_compare*/
    0,                         /*tp_repr*/
    0,                         /*tp_as_number*/
    0,                         /*tp_as_sequence*/
    0,                         /*tp_as_mapping*/
    0,                         /*tp_hash */
    pyIoMethod_call,                         /*tp_call*/
    0,                         /*tp_str*/
    0,                         /*tp_getattro*/
    0,                         /*tp_setattro*/
    0,                         /*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
    "pyIoMethod object",           /* tp_doc */
};

PyObject *initPyIoMethod(void) 
{
    pyIoMethodType.tp_new = PyType_GenericNew;
	return &pyIoMethodType;
}

PyObject *newPyIoMethod(IoObject *obj, IoSymbol *methodName) {
	pyIoMethodObject *o = PyObject_New(pyIoMethodObject, &pyIoMethodType);
	o->self = obj;
	o->methodName = methodName;
	return o;
}

